﻿using System;
using System.Collections.Generic;
using System.Reflection;

using NUnit.Framework;

using Yawf.Core.Exceptions;

namespace Yawf.Core.Reflection {
	/// <summary>
	/// Internal class to do some reflection testing
	/// </summary>
	class DummyReflectionClass {
		private String value1;
		private int value2;
		private long value3;
		private double value4;

		public String Value1 { get { return value1;} set { value1 = value;} }
		public int Value2 { get { return value2; } set { value2 = value; } }
		public long Value3 { get { return value3; } set { value3 = value; } }
		public double Value4 { get { return value4; } set { value4 = value; } }

		public void Method0() {
		}
		public void Method1(int param1) {
		}
		public void Method1(String param1) {
		}
		public void Method2(int param1,String param2) {
		}
	}
	
	[TestFixture]
	public class ReflectionUtilsTest {
		[Test]
		public void TestCreateInstance() {
			Object s;

			s = ReflectionUtils.CreateInstance("Yawf.Core.Exceptions.YawfException, Yawf.Core");
			Assert.IsInstanceOfType(typeof(YawfException), s, "s is not a VCGException");

			s = ReflectionUtils.CreateInstance("System.Object");
			Assert.IsInstanceOfType(typeof(Object),s,"s is not a Object");
		}

		[Test]
		public void TestIsSimpleType() {
			Assert.IsFalse(ReflectionUtils.IsSimpleType(null),"null is a simple type");
			Assert.IsFalse(ReflectionUtils.IsSimpleType(""),"'' is a simple type");
			Assert.IsFalse(ReflectionUtils.IsSimpleType("dasdsñadasd"),"'' is a simple type");
			Assert.IsTrue(ReflectionUtils.IsSimpleType("bool"),"'bool' is not a simple type");
			Assert.IsTrue(ReflectionUtils.IsSimpleType("byte"),"'byte' is not a simple type");
			Assert.IsTrue(ReflectionUtils.IsSimpleType("char"),"'char' is not a simple type");
			Assert.IsTrue(ReflectionUtils.IsSimpleType("double"),"'double' is not a simple type");
			Assert.IsTrue(ReflectionUtils.IsSimpleType("float"),"'float' is not a simple type");
			Assert.IsTrue(ReflectionUtils.IsSimpleType("int"),"'int' is not a simple type");
			Assert.IsTrue(ReflectionUtils.IsSimpleType("long"),"'long' is not a simple type");
			Assert.IsTrue(ReflectionUtils.IsSimpleType("short"),"'short' is not a simple type");
			Assert.IsTrue(ReflectionUtils.IsSimpleType("string"),"'string' is not a simple type");

			Assert.IsTrue(ReflectionUtils.IsSimpleType("System.Boolean"),"'System.Boolean' is not a simple type");
			Assert.IsTrue(ReflectionUtils.IsSimpleType("System.Byte"),"'System.Byte' is not a simple type");
			Assert.IsTrue(ReflectionUtils.IsSimpleType("System.Char"),"'System.Char' is not a simple type");
			Assert.IsTrue(ReflectionUtils.IsSimpleType("System.Double"),"'System.Double' is not a simple type");
			Assert.IsTrue(ReflectionUtils.IsSimpleType("System.Single"),"'System.Single' is not a simple type");
			Assert.IsTrue(ReflectionUtils.IsSimpleType("System.Int32"),"'System.Int32' is not a simple type");
			Assert.IsTrue(ReflectionUtils.IsSimpleType("System.Int64"),"'System.Int64' is not a simple type");
			Assert.IsTrue(ReflectionUtils.IsSimpleType("System.Int16"),"'System.Int16' is not a simple type");
			Assert.IsTrue(ReflectionUtils.IsSimpleType("System.String"),"'System.String' is not a simple type");
		}								// TestIsSimpleType

		[Test]
		public void TestGetSimpleType() {
			Object o;

			o = ReflectionUtils.GetSimpleType(null,"");
			Assert.AreSame(o,"","o != ''");
			Assert.AreEqual(ReflectionUtils.GetSimpleType("bool","true"),true,"'true' != 'true'");
			Assert.AreEqual(ReflectionUtils.GetSimpleType("byte","1"),1,"'1 byte' != '1'");
			Assert.AreEqual(ReflectionUtils.GetSimpleType("char","1"),'1',"'1' char != '1'");
			Assert.AreEqual(ReflectionUtils.GetSimpleType("double","1"),1,"'1' double != '1'");
			Assert.AreEqual(ReflectionUtils.GetSimpleType("float","1"),1,"'1' float != '1'");
			Assert.AreEqual(ReflectionUtils.GetSimpleType("int","1"),1,"'1' int != '1'");
			Assert.AreEqual(ReflectionUtils.GetSimpleType("long","1"),1,"'1' long != '1'");
			Assert.AreEqual(ReflectionUtils.GetSimpleType("short","1"),1,"'1' short != '1'");
			Assert.AreEqual(ReflectionUtils.GetSimpleType("String","1"),"1","'1' string != '1'");

			Assert.AreEqual(ReflectionUtils.GetSimpleType("System.Boolean","true"),true,"'true' != 'true'");
			Assert.AreEqual(ReflectionUtils.GetSimpleType("System.Byte","1"),1,"'1 byte' != '1'");
			Assert.AreEqual(ReflectionUtils.GetSimpleType("System.Char","1"),'1',"'1' char != '1'");
			Assert.AreEqual(ReflectionUtils.GetSimpleType("System.Double","1"),1,"'1' double != '1'");
			Assert.AreEqual(ReflectionUtils.GetSimpleType("System.Single","1"),1,"'1' float != '1'");
			Assert.AreEqual(ReflectionUtils.GetSimpleType("System.Int32","1"),1,"'1' int != '1'");
			Assert.AreEqual(ReflectionUtils.GetSimpleType("System.Int64","1"),1,"'1' long != '1'");
			Assert.AreEqual(ReflectionUtils.GetSimpleType("System.Int16","1"),1,"'1' short != '1'");
			Assert.AreEqual(ReflectionUtils.GetSimpleType("System.String","1"),"1","'1' string != '1'");
		}

		[Test]
		public void TestGetPropertyType() {
			Type t;

			t = ReflectionUtils.GetPropertyType(null,null);
			Assert.IsNull(t,"GetPropertyType(null,null) returns a non null value");

			t = ReflectionUtils.GetPropertyType("Hola","Length");
			Assert.AreEqual(t,typeof(Int32),"Length is not of type Int32");
		}

		[Test]
		public void TestSetProperty() {
			DummyReflectionClass tmpObject;

			ReflectionUtils.SetProperty(null,null,null);

			tmpObject = new DummyReflectionClass();
			ReflectionUtils.SetProperty(tmpObject,"Value1","Hola");
			Assert.AreEqual("Hola",tmpObject.Value1,"tmpObject.Value1 not set to 'Hola'");

			ReflectionUtils.SetProperty(tmpObject,"Value2",1);
			Assert.AreEqual(1,tmpObject.Value2,"tmpObject.Value2 not set to 1");

			ReflectionUtils.SetProperty(tmpObject,"Value3",1);
			Assert.AreEqual(1,tmpObject.Value3,"tmpObject.Value3 not set to 1");

			ReflectionUtils.SetProperty(tmpObject,"Value4",1);
			Assert.AreEqual(1,tmpObject.Value4,"tmpObject.Value4 not set to 1");
		}										// TestSetProperty

		[Test]
		public void TestFindMethodsByName() {
			DummyReflectionClass tmpObject;
			IList<MethodInfo> methods;

			tmpObject = new DummyReflectionClass();

			methods = ReflectionUtils.FindMethodsByName(tmpObject,null,3);
			Assert.IsNotNull(methods,"methods list is null");
			Assert.AreEqual(0,methods.Count,"methods.Count != 0");

			methods = ReflectionUtils.FindMethodsByName(tmpObject,"Method0",0);
			Assert.IsNotNull(methods,"methods list is null");
			Assert.AreEqual(1,methods.Count,"methods.Count != 1");

			methods = ReflectionUtils.FindMethodsByName(tmpObject,"Method1",1);
			Assert.IsNotNull(methods,"methods list is null");
			Assert.AreEqual(2,methods.Count,"methods.Count != 2");

			methods = ReflectionUtils.FindMethodsByName(tmpObject,"Method2",2);
			Assert.IsNotNull(methods,"methods list is null");
			Assert.AreEqual(1,methods.Count,"methods.Count != 1");
		}									// TestFindMethodsByName

		[Test]
		public void TestGetType() {
			Type t;

			t = ReflectionUtils.GetType("dsafasdsad");
			Assert.IsNull(t,"t is not null");
			t = ReflectionUtils.GetType("System.String");
			Assert.IsNotNull(t,"t is null");
			Assert.IsTrue(t.FullName == "System.String","t.FullName != 'System.String'");
		}

	}										// Class
}
